<template>
  <view class="hot-container">
    <!-- logo -->
    <image src="@/static/images/logo.png" class="logo" mode="aspectFit"></image>
    <!-- 搜索框 -->
    <view class="search-box" @click="onToSearch"><my-search placeholderText="uni-app 自定义组件"></my-search></view>
    <!-- tabs栏 -->
    <!-- 传入 :config="{textColor:'#00ff00'}" 能定制相应的主题 -->
    <my-tabs ref="myTabsRefs" :tabData="tabData" :defaultIndex="currentIndex" @tabsClick="tabsClick" />
    <!-- list视图 -->
    <!-- 
			5.让list 具备左右切换的能力
				5.1：思考如何让 list 拥有左右切换的能力
					 解决：使用Swiper对其进行改造
				5.2：问题1 - list 列表的高度展示错误
					 原因：没有为Swiper指定高度
					 解决：计算出每个item的高度，然后叠加到一起
				5.3：问题2-切换tab时，list的卡顿问题
					 原因：Swiper 动画未完成时，就获取数据 渲染DOM
					 解决：Swiper 动画完成之后，获取数据，渲染DOM
			6.完成list 与 tabs联动的能力
				6.1 tabs 切换时，Swiper 联动切换
				6.2 Swiper 切换时，tabs 联动切换
		 -->
    <!-- 
			功能补充：
				1.tabs 具备吸顶的效果
				2.控制列表滚动位置
					2.1 当用户滚动页面之后
					2.2 切换 tabs 时，让页面的滚动位置返回为 tabs吸顶的位置
		  
		  -->
    <!-- current 表示当前展示哪个 swiperItem  @animationfinish 动画结束时会触发 animationfinish 事件， @change 	current 改变时会触发 change 事件-->
    <swiper
      class="swiper"
      :style="{ height: swiperHeightData[currentIndex] + 'px' }"
      :current="currentIndex"
      @animationfinish="onSwiperEnd"
      @change="omSwiperChange"
    >
      <!-- swiperItem 的数量，需要由 tabData进行决定 -->
      <swiper-item class="swiper-item" v-for="(tabitem, tabindex) in tabData" :key="tabindex">
        <!-- {{tabindex}} 就是currentIndex -->
        <view>
          <!-- Loading -->
          <uni-load-more status="loading" v-if="isLoading"></uni-load-more>
          <!-- 列表 -->
          <block v-else>
            <!-- 列表循环的数据：listData[tabindex] listData[0]条数据中有几条就循环多少次hot-list-item -->
            <hot-list-item
              :class="'hot-list-item' + tabindex"
              v-for="(item, index) in listData[tabindex]"
              :key="index"
              :listData="item"
              :ranking="index + 1"
              @click.native="onItemClick(item)"
            >
            </hot-list-item>
          </block>
        </view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script>
import { _getHotTabs, _getHotList } from '../../api/hot/hot.js'
export default {
  data() {
    return {
      tabData: [], // tabs文章类型
      currentIndex: 0, // 默认tabs激活项
      isLoading: true, // list列表数据加载的 loading
      listData: {}, // 以index为key,以 对应的list为value
      currentSwiperHeight: 0, // 当前Swiper的高度
      swiperHeightData: {}, // 缓存高度的计算结果。以index 为key，以对应的高度 为value
      SwiperEnd: true, // 判断Swiper动画是否完成
      currentPageScrollTop: 0 // 当前的滚动距离
    }
  },
  created() {
    // this.getHotTabs()
  },
  mounted() {
    this.getHotTabs()

    console.log(this.swiperHeightData[this.currentIndex])
    console.log(this.currentSwiperHeight)
  },
  watch: {
    currentSwiperHeight: {
      handler() {
        console.log('1')
      },
      deep: true
    }
  },
  methods: {
    // 请求热搜文章类型
    async getHotTabs() {
      const result = await _getHotTabs()
      this.tabData = result.list
      this.getHotList(this.tabData[this.currentIndex].id) //默认请求激活项的文章
    },
    // tabs激活项
    tabsClick(index) {
      // 保存tabs激活项
      this.currentIndex = index
      // this.getHotList() 点击切换时在Swiper动画完成时再调用请求数据进行渲染
    },
    // 请求热搜文章列表
    async getHotList() {
      /**
       * 做数据缓存，请求过的数据不在请求
       * 1. 没有获取过数据
       * 1.1 展示loading
       * 1.2 调用接口获取数据
       * 1.3 把数据保存到本地
       * 1.4 隐藏loading
       *
       * 2. 已经获取过数据(有了缓存之后)
       * 2.1 直接渲染数据就可以了
       * */
      if (!this.listData[this.currentIndex]) {
        // 判断当前listData[key]有没有值，有则已请求过数据
        // 1
        // 1.1
        this.isLoading = true
        // 1.2
        const id = this.tabData[this.currentIndex].id
        const { list } = await _getHotList(id)
        // 1.3
        this.listData[this.currentIndex] = list // 当前激活项做listData的key添加对应的list文章数据
        // 1.4
        this.isLoading = false
        // console.log(this.listData)
        // 渲染完成数据之后，计算Swiper高度
        if (!this.swiperHeightData[this.currentIndex]) {
          // 判断缓存高度
          setTimeout(async () => {
            this.currentSwiperHeight = await this.getCurrentSwiperHeight()
            this.swiperHeightData[this.currentIndex] = this.currentSwiperHeight
            /* #ifdef H5 */
            this.$forceUpdate() // 解决H5中高度问题
            /* #endif */
            console.log(this.swiperHeightData[this.currentIndex])
          }, 0)
        }
      }
    },
    /**
     * 计算当前 Swiper高度
     * */
    getCurrentSwiperHeight() {
      return new Promise((resolve, reject) => {
        // 1.拿到所有的 item -> 异步
        let sum = 0
        const query = uni.createSelectorQuery().in(this)
        query
          .selectAll(`.hot-list-item${this.currentIndex}`)
          .boundingClientRect(res => {
            // 2.拿到所有 item 的高度
            // 3.把所有的高度累加
            console.log(res)
            res.forEach((item, index) => {
              sum += item.height
            })
            resolve(sum)
          })
          .exec()
      })
    },
    /**
     * 判断动画是否完成，执行渲染数据
     * 让动画Swiper执行完成后再执行渲染数据
     * */
    onSwiperEnd() {
      this.getHotList()
      // console.log('swiper动画完成')
    },
    /**
     * Swiper 切换时，tabs 联动切换
     * */
    omSwiperChange({ detail }) {
      if (this.currentPageScrollTop > 125) {
        uni.pageScrollTo({
          scrollTop: 125,
          duration: 200 // 滚动动画的时长，默认300ms，单位 ms
        })
      }
      this.currentIndex = detail.current // 切换的激活项重新赋值

      // 父调用子的方法 同步slider滑动快
      setTimeout(() => {
        // props是异步的，解决currentIndex最新值还没传给子组件去计算最新的slider left值
        this.$refs.myTabsRefs.tobToIndex()
      }, 0)

      // console.log('切换了',this.$refs.myTabsRefs.activeIndex)
    },
    /**
     * 监听页面的滚动
     * 直接使用这个方法即可，不需要绑定在dom，属于页面生命周期函数
     * */
    onPageScroll({ scrollTop }) {
      this.currentPageScrollTop = scrollTop
    },
    /**
     * 跳转到 search-blog 搜索
     * */
    onToSearch() {
      uni.navigateTo({
        url: '/subpkg/pages/search-blog/search-blog'
      })
    },
    /**
     * 跳转到 blog-detail 文章详情
     */
    onItemClick(item) {
      uni.navigateTo({
        url: `/subpkg/pages/blog-detail/blog-detail?author=${item.user_name}&articleId=${item.id}`
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.hot-container {
  background-color: $uni-bg-color;

  .logo {
    width: 100%;
    height: 80px;
  }

  .search-box {
    padding: 0 16px;
    margin-bottom: $uni-spacing-col-base;
  }
}
</style>
